<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Using OpenID Connect and Keycloak to Centralize Authorization</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/security-keycloak-authorization" />
  <meta property="og:title" content="Quarkus - Using OpenID Connect and Keycloak to Centralize Authorization" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/security-keycloak-authorization">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Using OpenID Connect and Keycloak to Centralize Authorization</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#architecture">Architecture</a></li>
<li><a href="#solution">Solution</a></li>
<li><a href="#creating-the-project">Creating the Project</a>
<ul class="sectlevel2">
<li><a href="#configuring-the-application">Configuring the application</a></li>
</ul>
</li>
<li><a href="#starting-and-configuring-the-keycloak-server">Starting and Configuring the Keycloak Server</a></li>
<li><a href="#running-and-using-the-application">Running and Using the Application</a>
<ul class="sectlevel2">
<li><a href="#running-in-developer-mode">Running in Developer Mode</a></li>
<li><a href="#running-in-jvm-mode">Running in JVM Mode</a></li>
<li><a href="#running-in-native-mode">Running in Native Mode</a></li>
</ul>
</li>
<li><a href="#testing-the-application">Testing the Application</a></li>
<li><a href="#checking-permissions-programmatically">Checking Permissions Programmatically</a></li>
<li><a href="#mapping-protected-resources">Mapping Protected Resources</a></li>
<li><a href="#more-about-configuring-protected-resources">More About Configuring Protected Resources</a></li>
<li><a href="#configuration-reference">Configuration Reference</a></li>
<li><a href="#references">References</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This guide demonstrates how your Quarkus application can authorize a bearer token access to protected resources using <a href="https://www.keycloak.org/docs/latest/authorization_services/index.html">Keycloak Authorization Services</a>.</p>
</div>
<div class="paragraph">
<p>The <code>quarkus-keycloak-authorization</code> extension is based on <code>quarkus-oidc</code> and provides a policy enforcer that enforces access to protected resources based on permissions managed by Keycloak and currently can only be used with the Quarkus <a href="security-openid-connect">OIDC service appications</a>.
It provides a flexible and dynamic authorization capability based on Resource-Based Access Control.
In other words, instead of explicitly enforcing access based on some specific access control mechanism (e.g.: RBAC), you just check whether or not a request is allowed to access a resource based on its name, identifier or URI.</p>
</div>
<div class="paragraph">
<p>By externalizing authorization from your application, you are allowed to protect your applications using different access control mechanisms as well as avoid re-deploying your application every time your security requirements change, where Keycloak will be acting as a centralized authorization service from where your protected resources and their associated permissions are managed.</p>
</div>
<div class="paragraph">
<p>If you are already familiar with Keycloak, you’ll notice that the extension is basically another adapter implementation but specific for Quarkus applications.
Otherwise, you can find more information in the Keycloak <a href="https://www.keycloak.org/docs/latest/authorization_services/index.html#_enforcer_overview">documentation</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="prerequisites"><a class="anchor" href="#prerequisites"></a>Prerequisites</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To complete this guide, you need:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>less than 15 minutes</p>
</li>
<li>
<p>an IDE</p>
</li>
<li>
<p>JDK 1.8+ installed with <code>JAVA_HOME</code> configured appropriately</p>
</li>
<li>
<p>Apache Maven 3.6.2+</p>
</li>
<li>
<p><a href="https://stedolan.github.io/jq/">jq tool</a></p>
</li>
<li>
<p><a href="https://www.keycloak.org/docs/latest/server_installation/index.html">Keycloak</a></p>
</li>
<li>
<p>Docker</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="architecture"><a class="anchor" href="#architecture"></a>Architecture</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In this example, we build a very simple microservice which offers two endpoints:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>/api/users/me</code></p>
</li>
<li>
<p><code>/api/admin</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>These endpoints are protected and can only be accessed if a client is sending a bearer token along with the request, which must be valid (e.g.: signature, expiration and audience) and trusted by the microservice.</p>
</div>
<div class="paragraph">
<p>The bearer token is issued by a Keycloak Server and represents the subject to which the token was issued for.
For being an OAuth 2.0 Authorization Server, the token also references the client acting on behalf of the user.</p>
</div>
<div class="paragraph">
<p>The <code>/api/users/me</code> endpoint can be accessed by any user with a valid token.
As a response, it returns a JSON document with details about the user where these details are obtained from the information carried on the token.
This endpoint is protected with RBAC (Role-Based Access Control) and only users granted with the <code>user</code> role can access this endpoint.</p>
</div>
<div class="paragraph">
<p>The <code>/api/admin</code> endpoint is protected with RBAC (Role-Based Access Control) and only users granted with the <code>admin</code> role can access it.</p>
</div>
<div class="paragraph">
<p>This is a very simple example using RBAC policies to govern access to your resources.
However, Keycloak supports other types of policies that you can use to perform even more fine-grained access control.
By using this example, you&#8217;ll see that your application is completely decoupled from your authorization policies with enforcement being purely based on the accessed resource.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="solution"><a class="anchor" href="#solution"></a>Solution</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We recommend that you follow the instructions in the next sections and create the application step by step.
However, you can go right to the completed example.</p>
</div>
<div class="paragraph">
<p>Clone the Git repository: <code>git clone <a href="https://github.com/quarkusio/quarkus-quickstarts.git" class="bare">https://github.com/quarkusio/quarkus-quickstarts.git</a></code>, or download an <a href="https://github.com/quarkusio/quarkus-quickstarts/archive/master.zip">archive</a>.</p>
</div>
<div class="paragraph">
<p>The solution is located in the <code>security-keycloak-authorization-quickstart</code> <a href="https://github.com/quarkusio/quarkus-quickstarts/tree/master/security-keycloak-authorization-quickstart">directory</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-the-project"><a class="anchor" href="#creating-the-project"></a>Creating the Project</h2>
<div class="sectionbody">
<div class="paragraph">
<p>First, we need a new project.
Create a new project with the following command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=security-keycloak-authorization-quickstart \
    -Dextensions="oidc, keycloak-authorization, resteasy-jsonb"
cd security-keycloak-authorization-quickstart</code></pre>
</div>
</div>
<div class="paragraph">
<p>This command generates a Maven project, importing the <code>keycloak-authorization</code> extension which is an implementation of a Keycloak Adapter for Quarkus applications and provides all the necessary capabilities to integrate with a Keycloak Server and perform bearer token authorization.</p>
</div>
<div class="paragraph">
<p>If you already have your Quarkus project configured, you can add the <code>oidc</code> and <code>keycloak-authorization</code> extensions
to your project by running the following command in your project base directory:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">./mvnw quarkus:add-extension -Dextensions="oidc,keycloak-authorization"</code></pre>
</div>
</div>
<div class="paragraph">
<p>This will add the following to your <code>pom.xml</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-oidc&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-keycloak-authorization&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Let&#8217;s start by implementing the <code>/api/users/me</code> endpoint.
As you can see from the source code below it is just a regular JAX-RS resource:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.security.keycloak.authorization;;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.jboss.resteasy.annotations.cache.NoCache;

import io.quarkus.security.identity.SecurityIdentity;

@Path("/api/users")
public class UsersResource {

    @Inject
    SecurityIdentity identity;

    @GET
    @Path("/me")
    @Produces(MediaType.APPLICATION_JSON)
    @NoCache
    public User me() {
        return new User(identity);
    }

    public static class User {

        private final String userName;

        User(SecurityIdentity identity) {
            this.userName = identity.getPrincipal().getName();
        }

        public String getUserName() {
            return userName;
        }
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The source code for the <code>/api/admin</code> endpoint is also very simple:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.security.keycloak.authorization;;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import io.quarkus.security.Authenticated;

@Path("/api/admin")
@Authenticated
public class AdminResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String admin() {
        return "granted";
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that we did not define any annotation such as <code>@RoleAllowed</code> to explicitly enforce access to a resource.
The extension will be responsible to map the URIs of the protected resources you have in Keycloak and evaluate the permissions accordingly, granting or denying access depending on the permissions that will be granted by Keycloak.</p>
</div>
<div class="sect2">
<h3 id="configuring-the-application"><a class="anchor" href="#configuring-the-application"></a>Configuring the application</h3>
<div class="paragraph">
<p>The OpenID Connect extension allows you to define the adapter configuration using the <code>application.properties</code> file which should be located at the <code>src/main/resources</code> directory.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs"># OIDC Configuration
quarkus.oidc.auth-server-url=http://localhost:8180/auth/realms/quarkus
quarkus.oidc.client-id=backend-service
quarkus.oidc.credentials.secret=secret

# Enable Policy Enforcement
quarkus.keycloak.policy-enforcer.enable=true</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
By default, applications using the <code>quarkus-oidc</code> extension are marked as a <code>service</code> type application (see <code>quarkus.oidc.application-type</code>). This extension currently supports only such <code>service</code> type applications.
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="starting-and-configuring-the-keycloak-server"><a class="anchor" href="#starting-and-configuring-the-keycloak-server"></a>Starting and Configuring the Keycloak Server</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To start a Keycloak Server you can use Docker and just run the following command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">docker run --name keycloak -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin -p 8180:8080 {keycloak-docker-image}</code></pre>
</div>
</div>
<div class="paragraph">
<p>You should be able to access your Keycloak Server at <a href="http://localhost:8180/auth">localhost:8180/auth</a>.</p>
</div>
<div class="paragraph">
<p>Log in as the <code>admin</code> user to access the Keycloak Administration Console.
Username should be <code>admin</code> and password <code>admin</code>.</p>
</div>
<div class="paragraph">
<p>Import the <a href="https://github.com/quarkusio/quarkus-quickstarts/tree/master/security-keycloak-authorization-quickstart/config/quarkus-realm.json">realm configuration file</a> to create a new realm.
For more details, see the Keycloak documentation about how to <a href="https://www.keycloak.org/docs/latest/server_admin/index.html#_create-realm">create a new realm</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="running-and-using-the-application"><a class="anchor" href="#running-and-using-the-application"></a>Running and Using the Application</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="running-in-developer-mode"><a class="anchor" href="#running-in-developer-mode"></a>Running in Developer Mode</h3>
<div class="paragraph">
<p>To run the microservice in dev mode, use <code>./mvnw clean compile quarkus:dev</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="running-in-jvm-mode"><a class="anchor" href="#running-in-jvm-mode"></a>Running in JVM Mode</h3>
<div class="paragraph">
<p>When you&#8217;re done playing with "dev-mode" you can run it as a standard Java application.</p>
</div>
<div class="paragraph">
<p>First compile it:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">./mvnw package</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then run it:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">java -jar ./target/security-keycloak-authorization-quickstart-runner.jar</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="running-in-native-mode"><a class="anchor" href="#running-in-native-mode"></a>Running in Native Mode</h3>
<div class="paragraph">
<p>This same demo can be compiled into native code: no modifications required.</p>
</div>
<div class="paragraph">
<p>This implies that you no longer need to install a JVM on your production environment, as the runtime technology is included in the produced binary, and optimized to run with minimal resource overhead.</p>
</div>
<div class="paragraph">
<p>Compilation will take a bit longer, so this step is disabled by default; let&#8217;s build again by enabling the <code>native</code> profile:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">./mvnw package -Pnative</code></pre>
</div>
</div>
<div class="paragraph">
<p>After getting a cup of coffee, you&#8217;ll be able to run this binary directly:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">./target/security-keycloak-authorization-quickstart-runner</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="testing-the-application"><a class="anchor" href="#testing-the-application"></a>Testing the Application</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The application is using bearer token authorization and the first thing to do is obtain an access token from the Keycloak Server in order to access the application resources:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">export access_token=$(\
    curl -X POST http://localhost:8180/auth/realms/quarkus/protocol/openid-connect/token \
    --user backend-service:secret \
    -H 'content-type: application/x-www-form-urlencoded' \
    -d 'username=alice&amp;password=alice&amp;grant_type=password' | jq --raw-output '.access_token' \
 )</code></pre>
</div>
</div>
<div class="paragraph">
<p>The example above obtains an access token for user <code>alice</code>.</p>
</div>
<div class="paragraph">
<p>Any user is allowed to access the
<code><a href="http://localhost:8080/api/users/me" class="bare">http://localhost:8080/api/users/me</a></code> endpoint
which basically returns a JSON payload with details about the user.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">curl -v -X GET \
  http://localhost:8080/api/users/me \
  -H "Authorization: Bearer "$access_token</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code><a href="http://localhost:8080/api/admin" class="bare">http://localhost:8080/api/admin</a></code> endpoint can only be accessed by users with the <code>admin</code> role.
If you try to access this endpoint with the previously issued access token, you should get a <code>403</code> response from the server.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs"> curl -v -X GET \
   http://localhost:8080/api/admin \
   -H "Authorization: Bearer "$access_token</code></pre>
</div>
</div>
<div class="paragraph">
<p>In order to access the admin endpoint you should obtain a token for the <code>admin</code> user:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">export access_token=$(\
    curl -X POST http://localhost:8180/auth/realms/quarkus/protocol/openid-connect/token \
    --user backend-service:secret \
    -H 'content-type: application/x-www-form-urlencoded' \
    -d 'username=admin&amp;password=admin&amp;grant_type=password' | jq --raw-output '.access_token' \
 )</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="checking-permissions-programmatically"><a class="anchor" href="#checking-permissions-programmatically"></a>Checking Permissions Programmatically</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In some cases, you may want to programmatically check whether or not a request is granted to access a protected resource. By
injecting a <code>SecurityIdentity</code> instance in your beans, you are allowed to check permissions as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Path("/api/protected")
public class ProtectedResource {

    @Inject
    SecurityIdentity identity;


    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public CompletionStage&lt;List&lt;Permission&gt;&gt; get() {
        return identity.checkPermission(new AuthPermission("{resource_name}"))
                .thenCompose(granted -&gt; {
                    if (granted) {
                        return CompletableFuture.completedFuture(doGetState());
                    }
                    throw new ForbiddenException();
                });
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="mapping-protected-resources"><a class="anchor" href="#mapping-protected-resources"></a>Mapping Protected Resources</h2>
<div class="sectionbody">
<div class="paragraph">
<p>By default, the extension is going to fetch resources on-demand from Keycloak where their <code>URI</code> are used to map the resources in your application that should be protected.</p>
</div>
<div class="paragraph">
<p>If you want to disable this behavior and fetch resources during startup, you can use the following configuration:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs">quarkus.keycloak.policy-enforcer.lazy-load-paths=false</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that, depending on how many resources you have in Keycloak the time taken to fetch them may impact your application startup time.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="more-about-configuring-protected-resources"><a class="anchor" href="#more-about-configuring-protected-resources"></a>More About Configuring Protected Resources</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In the default configuration, Keycloak is responsible for managing the roles and deciding who can access which routes.</p>
</div>
<div class="paragraph">
<p>To configure the protected routes using the <code>@RolesAllowed</code> annotation or the <code>application.properties</code> file, check the <a href="security-openid-connect">Using OpenID Connect Adapter to Protect JAX-RS Applications</a> guide. For more details, check the <a href="security">Security guide</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="configuration-reference"><a class="anchor" href="#configuration-reference"></a>Configuration Reference</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The configuration is based on the official <a href="https://www.keycloak.org/docs/latest/authorization_services/index.html#_enforcer_filter">Keycloak Policy Enforcer Configuration</a>. If you are looking for more details about the different configuration options, please take a look at this documentation,</p>
</div>
<div class="paragraph configuration-legend">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> Configuration property fixed at build time - All other configuration properties are overridable at runtime</p>
</div>
<table class="tableblock frame-all grid-all stretch configuration-reference">
<colgroup>
<col style="width: 80%;">
<col style="width: 10%;">
<col style="width: 10%;">
</colgroup>
<tbody>
<tr>
<th class="tableblock halign-left valign-top"><p class="tableblock"><a id="quarkus-keycloak-keycloak-policy-enforcer-config_configuration"></a><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_configuration">Configuration property</a></p></th>
<th class="tableblock halign-left valign-middle"><p class="tableblock">Type</p></th>
<th class="tableblock halign-left valign-middle"><p class="tableblock">Default</p></th>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.connection-pool-size"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.connection-pool-size">quarkus.keycloak.connection-pool-size</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>Adapters will make separate HTTP invocations to the Keycloak server to turn an access code into an access token. This config option defines how many connections to the Keycloak server should be pooled</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">int</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>20</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.enable"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.enable">quarkus.keycloak.policy-enforcer.enable</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>Enables policy enforcement.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">boolean</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>false</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.enforcement-mode"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.enforcement-mode">quarkus.keycloak.policy-enforcer.enforcement-mode</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>Specifies how policies are enforced.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>permissive</code>, <code>enforcing</code>, <code>disabled</code></p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>enforcing</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.path-cache.max-entries"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.path-cache.max-entries">quarkus.keycloak.policy-enforcer.path-cache.max-entries</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>Defines the limit of entries that should be kept in the cache</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">int</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>1000</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.path-cache.lifespan"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.path-cache.lifespan">quarkus.keycloak.policy-enforcer.path-cache.lifespan</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>Defines the time in milliseconds when the entry should be expired</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">long</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>30000</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.lazy-load-paths"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.lazy-load-paths">quarkus.keycloak.policy-enforcer.lazy-load-paths</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>Specifies how the adapter should fetch the server for resources associated with paths in your application. If true, the policy enforcer is going to fetch resources on-demand accordingly with the path being requested</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">boolean</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>true</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.http-method-as-scope"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.http-method-as-scope">quarkus.keycloak.policy-enforcer.http-method-as-scope</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>Specifies how scopes should be mapped to HTTP methods. If set to true, the policy enforcer will use the HTTP method from the current request to check whether or not access should be granted</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">boolean</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>false</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.name"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.name">quarkus.keycloak.policy-enforcer.paths."paths".name</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>The name of a resource on the server that is to be associated with a given path</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-middle"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.path"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.path">quarkus.keycloak.policy-enforcer.paths."paths".path</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>A URI relative to the application’s context path that should be protected by the policy enforcer</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-middle"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.methods.-methods-.method"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.methods.-methods-.method">quarkus.keycloak.policy-enforcer.paths."paths".methods."methods".method</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>The name of the HTTP method</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">required <span class="icon"><i class="fa fa-exclamation-circle" title="Configuration property is required"></i></span></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.methods.-methods-.scopes"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.methods.-methods-.scopes">quarkus.keycloak.policy-enforcer.paths."paths".methods."methods".scopes</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>An array of strings with the scopes associated with the method</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">list of string</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">required <span class="icon"><i class="fa fa-exclamation-circle" title="Configuration property is required"></i></span></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.methods.-methods-.scopes-enforcement-mode"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.methods.-methods-.scopes-enforcement-mode">quarkus.keycloak.policy-enforcer.paths."paths".methods."methods".scopes-enforcement-mode</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>A string referencing the enforcement mode for the scopes associated with a method</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>all</code>, <code>any</code>, <code>disabled</code></p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>all</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.enforcement-mode"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.enforcement-mode">quarkus.keycloak.policy-enforcer.paths."paths".enforcement-mode</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>Specifies how policies are enforced</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>permissive</code>, <code>enforcing</code>, <code>disabled</code></p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>enforcing</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.claim-information-point-complex-config"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.claim-information-point-complex-config">quarkus.keycloak.policy-enforcer.paths."paths".claim-information-point</a></code></p>
</div>
<div class="openblock description">
<div class="content">

</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Map&lt;String,Map&lt;String,Map&lt;String,String&gt;&gt;&gt;</code></p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">required <span class="icon"><i class="fa fa-exclamation-circle" title="Configuration property is required"></i></span></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.claim-information-point-simple-config"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.paths.-paths-.claim-information-point-simple-config">quarkus.keycloak.policy-enforcer.paths."paths".claim-information-point</a></code></p>
</div>
<div class="openblock description">
<div class="content">

</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Map&lt;String,Map&lt;String,String&gt;&gt;</code></p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">required <span class="icon"><i class="fa fa-exclamation-circle" title="Configuration property is required"></i></span></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.claim-information-point-complex-config"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.claim-information-point-complex-config">quarkus.keycloak.policy-enforcer.claim-information-point</a></code></p>
</div>
<div class="openblock description">
<div class="content">

</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Map&lt;String,Map&lt;String,Map&lt;String,String&gt;&gt;&gt;</code></p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">required <span class="icon"><i class="fa fa-exclamation-circle" title="Configuration property is required"></i></span></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.claim-information-point-simple-config"></a><code><a href="#quarkus-keycloak-keycloak-policy-enforcer-config_quarkus.keycloak.policy-enforcer.claim-information-point-simple-config">quarkus.keycloak.policy-enforcer.claim-information-point</a></code></p>
</div>
<div class="openblock description">
<div class="content">

</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Map&lt;String,Map&lt;String,String&gt;&gt;</code></p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">required <span class="icon"><i class="fa fa-exclamation-circle" title="Configuration property is required"></i></span></p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect1">
<h2 id="references"><a class="anchor" href="#references"></a>References</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p><a href="https://www.keycloak.org/documentation.html">Keycloak Documentation</a></p>
</li>
<li>
<p><a href="https://www.keycloak.org/docs/latest/authorization_services/index.html">Keycloak Authorization Services Documentation</a></p>
</li>
<li>
<p><a href="https://openid.net/connect/">OpenID Connect</a></p>
</li>
<li>
<p><a href="https://tools.ietf.org/html/rfc7519">JSON Web Token</a></p>
</li>
</ul>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
